#ifndef _RESOURCE_DISPATCHER_8ED32209_6606_4FCD_BD7E_88AA32AA5B46_
#define _RESOURCE_DISPATCHER_8ED32209_6606_4FCD_BD7E_88AA32AA5B46_
#pragma once
#include "base/threading/non_thread_safe.h"
#include "net/base/io_buffer.h"
#include "work_channel.h"
#include "common/message.h"
#include "work_thread.h"
#include "url_defines.h"
#include "resource_download.h"
#include "resource_storage.h"
#include "speed_statistics.h"

namespace dl {

/**
 * 资源分派处理
 * 负责解析URL的请求消息以及下载过程的处理
 */
class ResourceDispatcher : public MessageTransfer,
                           public WorkThread::Delegate,
                           public base::NonThreadSafe {
private:
  // URL请求上下文:封装URL请求的相关信息(编号、管道、下载请求信息等)
  struct RequestContext : public base::RefCounted<RequestContext> {
    typedef std::pair<int64, int64> ContentLengthPair;
    WorkChannelVector  channels;
    URLRequestData     request_data;
    SpeedStatistics    speed_statistics;
    ContentLengthPair  content_length;       
    static RequestContext* Create(WorkChannel* c, URLRequestData data);
  };
  typedef scoped_refptr<RequestContext> RequestContextPtr;

  // 实现ResourceDownload::ResponseDelegate接口, 运行在下载IO线程
  // 负责将数据封装并抛到主线程做处理
  struct ResponseHandler : public ResourceDownload::ResponseDelegate {
    explicit ResponseHandler(ResourceDispatcher& d);
    virtual bool OnResponseStarted(unsigned int symbol, ResponsePtr response);
    virtual void OnReadCompleted(unsigned int symbol, IOBufferWithSizePtr buffer);
    virtual void OnResponseFinished(unsigned int symbol, net::URLRequestStatus stat);
    ResourceDispatcher& dispatcher;
  };

  // 实现ResourceStorage::StorageDelegate接口, 运行在文件存储IO线程
  // 负责将数据封装并抛到主线程做处理
  struct StorageHandler : public ResourceStorage::StorageDelegate {
    explicit StorageHandler(ResourceDispatcher& d);
    virtual void OnCreateStorageCompleted(unsigned int symbol, int64 start_position);
    ResourceDispatcher& dispatcher;
  };

public:
  ResourceDispatcher();
  virtual ~ResourceDispatcher();
  // 清除资源
  void Clear();

private:
  bool CreateDownloadThread();
  bool CreateFileThread();

  // MessageTransfer 接口
  virtual bool OnMessageDispatch(WorkChannel* channel, const IPC::Message& message);

  // IPC消息处理
  void OnRequestDownload(WorkChannel* channel,
      unsigned int symbol, const MSG_Request_Param& param);
  void OnCancelDownload(WorkChannel* channel, unsigned int symbol);

  void OnResponseStarted(unsigned int symbol, ResponsePtr response);
  void OnReadCompleted(unsigned int symbol, IOBufferWithSizePtr buffer);
  void OnResponseFinished(unsigned int symbol, net::URLRequestStatus stat);

  void OnCreateStorageCompleted(unsigned int symbol, int64 start_position);

  void OnNotifyProgress(unsigned int symbol, RequestContextPtr context);

  // WorkThread::Delegate接口
  virtual void OnInit(WorkThread* thr);
  virtual void OnCleanup(WorkThread* thr);

private:
  typedef std::map<unsigned int, RequestContextPtr> RequestContextMap;
  RequestContextMap request_context_;

  scoped_ptr<ResponseHandler> response_handler_;
  scoped_ptr<StorageHandler>  storage_handler_;
  scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
  scoped_ptr<ResourceDownload> download_;
  scoped_ptr<ResourceStorage> storage_;
  scoped_ptr<WorkThread> download_thread_;     // URL下载线程
  scoped_ptr<WorkThread> file_thread_;         // 文件读写线程
};

}

#endif//_RESOURCE_DISPATCHER_8ED32209_6606_4FCD_BD7E_88AA32AA5B46_